from __future__ import print_function
from imutils.object_detection import non_max_suppression
from imutils import paths
from concurrent.futures import ProcessPoolExecutor
import numpy as np
import argparse
import time
import pandas as pd
import imutils
import cv2
#cap = cv2.VideoCapture("F:\\py\\camHumDetect\\img\\bd1627e63900eb94db93cab16e0cd5bc.mp4")
cap = cv2.VideoCapture("rtsp://admin:admin12345@192.168.1.230:554/h264/ch36/main/av_stream")
#print (cap.isOpened())
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
def humDet(filt = "NMS", threshold = 0):
	fps = 0
	while cap.isOpened():
		ret,frame = cap.read()
		mat_start = time.time()
		image = frame
		#用灰度图检测，加快检测速度
		if(fps % 15 ==0):
			orig = image.copy()
			orig = cv2.UMat(orig) 
			orig = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
			(rects, weights) = hog.detectMultiScale(orig, winStride=(8, 8), padding=(16,16), scale=1.2)
			rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
			#print("检测到人体：", len(rects))
			if filt == "NMS":
				pick = NMSFilter(rects)
			elif filt == "WF":
				pick = WeightFilter(rects, weights, threshold)
			else:
				pick = rects

			for (xA, yA, xB, yB) in pick:
				cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2)#对角线画法
			print('humDet: %f s...' % (time.time() - mat_start))

		cv2.imshow("humanDetect" + filt,image)
		fps +=1
		cv2.waitKey(1)

def humDetXml():
    fps = 0
    hog = cv2.HOGDescriptor()
    hog.setSVMDetector( cv2.HOGDescriptor_getDefaultPeopleDetector() )

    #face dection xml file
    faceCascade = cv2.CascadeClassifier("face.xml")

    #resize video size
    width = 640
    height = 320
    cap.set(3, width)
    cap.set(4, height)

    while True:
        #read stream live video
        width = 640
        height = 320
        cap.set(3, width)
        cap.set(4, height)
        ret, img = cap.read()
        #Convert BGR to GRAY
        if(fps % 15 ==0):
            mat_start = time.time()
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
	        #BONUS: face detection
            faces = faceCascade.detectMultiScale(
                gray,
                scaleFactor=1.2,
                minNeighbors=5,
                minSize=(30, 30)
            )
	        #draw_rectangle
            for (x, y, w, h) in faces:
                cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
	        #detect pedestrians in our video using the detectMultiScale  function
            found, w = hog.detectMultiScale(img, winStride=(8, 8), padding=(32, 32), scale=1.05)
            found_filtered = []
            for ri, r in enumerate(found):
                for qi, q in enumerate(found):
                    if ri != qi and inside(r, q):
                        break
                else:
                    found_filtered.append(r)
            draw_detections(img, found)
            draw_detections(img, found_filtered, 3)
	        #print('%d (%d) found' % (len(found_filtered), len(found)))
            print('humXml: %f s...' % (time.time() - mat_start))
        cv2.imshow('humDetXml', img)
        fps +=1
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    cv2.waitKey(0)
def inside(r, q):
    rx, ry, rw, rh = r
    qx, qy, qw, qh = q
    return rx > qx and ry > qy and rx + rw < qx + qw and ry + rh < qy + qh

def draw_detections(img, rects, thickness = 1):
    for x, y, w, h in rects:
        # the HOG detector returns slightly larger rectangles than the real objects.
        # so we slightly shrink the rectangles to get a nicer output.
        pad_w, pad_h = int(0.15*w), int(0.05*h)
        cv2.rectangle(img, (x+pad_w, y+pad_h), (x+w-pad_w, y+h-pad_h), (0, 255, 0), thickness)
def realtimeVideo():
	while cap.isOpened():
		ret,frame = cap.read()
		cv2.imshow("video",frame)
		cv2.waitKey(1)

def NMSFilter(rects):
	#修正多余的画框
	pick = non_max_suppression(rects, probs=None, overlapThresh=0.65)
	return pick

def WeightFilter(rects, weights, threshold = 0.7):
	if len(rects) <= 0:
		#print("未检测到人体，", rects)
		return rects
	recW = np.hstack((rects, weights))
	#print(rects, weights)
	dfRecW = pd.DataFrame(recW, columns=('xA', 'yA', 'xB', 'yB', 'weights'))
	dfRecW = dfRecW.sort_values(by='weights', ascending=False)
	pick = np.int32(dfRecW[dfRecW.weights > threshold])
	if pick.size >= 1:
		return tuple(pick[:,:4])
	else :
		return []

if __name__ == '__main__':
	p = ProcessPoolExecutor(3)
	#p.submit(humDet, "NMS")
	p.submit(humDet, "WF", 0.6)
	p.submit(humDetXml)
	p.submit(realtimeVideo)

